#pragma once

#include <cstdint>
#include "../timer_queue.hh"

namespace kratos { namespace corelib {

class TimerQueue;
using EventID = std::uint32_t; // Event ID type

// Event base class
class EventObject {
    friend class EventQueue;

public:
    // ctor
    EventObject();
    // dtor
    virtual ~EventObject();

public:
    // give you a chance to cancel un-finished event
    void cancel();
    // Is event cancelled?
    // @retval true
    // @retval false
    bool isCancelled() const;
    // set event ID
    void setEventID(EventID eventID);
    // query event ID
    EventID getEventID() const;
    // set sender ID
    void setSender(std::uint64_t sender);
    // query sender ID
    std::uint64_t getSender() const;
    // set receiver ID
    void setReceiver(std::uint64_t receiver);
    // query receiver ID
    std::uint64_t getReceiver() const;

private:
    // dispose event object, DONOT implements it!
    virtual void dispose() = 0;

private:
    // set TimerQueue
    // @param timerQueue TimerQueue
    void setTimerQueue(TimerQueue* timerQueue);
    // query TimerQueue
    TimerQueue* getTimerQueue() const;
    // set timer ID
    void setTimerID(TimerID timerID);
    // query timer ID
    TimerID getTimerID();
    // set flag, same event instance can ONLY fire once
    void fire();
    // query flag
    bool isFired();
    // set periodical flag
    void setPeriod();
    // Is periodical?
    bool isPeriod();

private:
    EventID eventID_; // event ID
    std::uint64_t sender_; // event sender ID
    std::uint64_t receiver_; // event receiver ID
    TimerID timerID_; // timer ID
    bool cancelled_; // cancelled? true of false
    TimerQueue* timerQueue_; // timer queue
    bool fired_; // already fired
    bool period_; // Is periodical?
};

}}
